package com.ruoyi.web.core.mybatis.driver;

import cn.hutool.core.util.StrUtil;
import com.ruoyi.web.core.mybatis.anno.SimpleID;
import com.ruoyi.web.core.mybatis.anno.SimpleIgnore;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
import org.apache.ibatis.session.Configuration;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Insert
 */
@Slf4j
public class SimpleUpdateDriver extends XMLLanguageDriver implements LanguageDriver {

    @Override
    public SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType) {
        Field[] fields = parameterType.getDeclaredFields();
        Set<Field> ids = Arrays.stream(fields).filter(f -> f.isAnnotationPresent(SimpleID.class)).collect(Collectors.toSet());
        if (ids.size() == 0) {
            throw new RuntimeException("ERR: MISSING @SimpleID PROPERTIES!");
        }
        StringBuilder sql = new StringBuilder();
        String tableName = StrUtil.toUnderlineCase(parameterType.getSimpleName()).toLowerCase();
        sql.append(" update ").append(tableName).append(" <trim prefix=\"SET\" suffixOverrides=\",\">");
        Arrays.stream(fields)
                .filter(f -> !f.isAnnotationPresent(SimpleID.class) && !f.isAnnotationPresent(SimpleIgnore.class))
                .forEach(f -> {
                    String fn = f.getName();
                    sql.append("<if test=\"").append(fn).append(" != null \"> ").append(StrUtil.toUnderlineCase(fn)).append(" = #{").append(fn).append("},</if>");
                });
        sql.append(" </trim> ");
        sql.append(" where 1=1 ");
        ids.forEach(id -> sql.append(" and ").append(StrUtil.toUnderlineCase(id.getName())).append(" = ").append("#{").append(id.getName()).append("}"));
        script = "<script>" + sql.toString() + "</script>";
        return super.createSqlSource(configuration, script, parameterType);
    }
}
